/*
 * Direction.cpp
 *
 *  Created on: 06/05/2011
 *      Author: DessaVida
 */

#include "Direction.h"
#include <iostream>
#include "entity/component/Shoot.h"

Direction::Direction(int id):Component(id) {
	dir = SOUTH;

}

/*
 * \dirName name of direction in capital letter.
 */
Direction::Direction(int id, string dirName):Component(id)
{
	if(dirName.compare("NORTH") == 0)
		dir = NORTH;
	if(dirName.compare("SOUTH") == 0)
		dir = SOUTH;
	if(dirName.compare("EAST") == 0)
		dir = EAST;
	if(dirName.compare("WEST") == 0)
		dir = WEST;

	previousDir = SOUTH;
}

Direction::~Direction() {
	// TODO Auto-generated destructor stub
}

void Direction::set(Controller *controller)
{
	if(controller->getDOWN())
		dir = SOUTH;
	if(controller->getUP())
		dir = NORTH;
	if(controller->getRIGHT())
		dir = EAST;
	if(controller->getLEFT())
		dir = WEST;


}

void Direction::update(Body* body)
{
	if(previousDir != dir)
	{
		if(body->getCollision()){
			body->setCollisionBody( rotate(body->getRawCollisionArea(), body->getCollisionCenter()));
		}
		if(body->getDamage()){
//			body->setDamageBody( rotate(body->getRawDamageArea(), body->getDamageCenter()));
		}
		if(body->getAction()){
			body->setActionArea( rotate(body->getRawActionArea(), body->getActionCenter()));
		}
		if(body->getInteract()){
			body->setInteractPoint( rotate(body->getRawInteractPoint(), body->getInteractCenter()));
		}
		if(body->getStrike()){
			body->setStrikeArea( rotate(body->getRawStrikeArea(), body->getStrikeCenter()));
		}
	}
}

void Direction::update(Body* body, Attack *attack, Shoot *shoot)
{
	update(body);

	if(previousDir != dir)
	{
		if(attack)
			attack->setAttackArea( rotate(attack->getAttackArea(), attack->getAttackCenter()));
		if(shoot)
			shoot->setShootPoint( rotate(shoot->getShootPoint(), shoot->getShootCenter()));
	}
}

Rectangle Direction::rotate(Rectangle rect, Point2D origin)
{
	Rectangle newArea = rect;
	if(dir == SOUTH){
		if(previousDir == EAST)
			newArea = rect.Rotate(origin, 3);
		if(previousDir == NORTH)
			newArea = rect.Rotate(origin, 2);
		if(previousDir == WEST)
			newArea = rect.Rotate(origin, 1);
	}
	if(dir == EAST){
		if(previousDir == NORTH)
			newArea = rect.Rotate(origin, 3);
		if(previousDir == WEST)
			newArea = rect.Rotate(origin, 2);
		if(previousDir == SOUTH)
			newArea = rect.Rotate(origin, 1);
	}
	if(dir == NORTH){
		if(previousDir == WEST)
			newArea = rect.Rotate(origin, 3);
		if(previousDir == SOUTH)
			newArea = rect.Rotate(origin, 2);
		if(previousDir == EAST)
			newArea = rect.Rotate(origin, 1);
	}
	if(dir == WEST){
		if(previousDir == SOUTH)
			newArea = rect.Rotate(origin, 3);
		if(previousDir == EAST)
			newArea = rect.Rotate(origin, 2);
		if(previousDir == NORTH)
			newArea = rect.Rotate(origin, 1);
	}

	return newArea;
}

Point2D Direction::rotate(Point2D point, Point2D origin)
{
	Point2D newPoint = point;
	if(dir == SOUTH){
		if(previousDir == EAST)
			newPoint = point.Rotate(origin, 1);
		if(previousDir == NORTH)
			newPoint = point.Rotate(origin, 2);
		if(previousDir == WEST)
			newPoint = point.Rotate(origin, 3);
	}
	if(dir == EAST){
		if(previousDir == NORTH)
			newPoint = point.Rotate(origin, 1);
		if(previousDir == WEST)
			newPoint = point.Rotate(origin, 2);
		if(previousDir == SOUTH)
			newPoint = point.Rotate(origin, 3 );
//		if(newPoint.getX() < 0)
//			newPoint.setX((-1) * newPoint.getX());
	}
	if(dir == NORTH){
		if(previousDir == WEST)
			newPoint = point.Rotate(origin, 1);
		if(previousDir == SOUTH)
			newPoint = point.Rotate(origin, 2);
		if(previousDir == EAST)
			newPoint = point.Rotate(origin, 3);
	}
	if(dir == WEST){
		if(previousDir == SOUTH)
			newPoint = point.Rotate(origin, 1);
		if(previousDir == EAST)
			newPoint = point.Rotate(origin, 2);
		if(previousDir == NORTH)
			newPoint = point.Rotate(origin, 3);
	}

	return newPoint;
}

/*
 * Getters and Setters
 */
EnumDirection Direction::getDir() const
{
	return dir;
}



EnumDirection Direction::getPreviousDir() const
{
    return previousDir;
}

void Direction::setPreviousDir(EnumDirection previousDir)
{
    this->previousDir = previousDir;
}

void Direction::setDir(EnumDirection dir)
{
    this->dir = dir;
}
